import re
import json
from datetime import datetime

from django.db.models import Q
from django.views import View
from django.http import JsonResponse
from django.core.paginator import Paginator

from .models import House, HouseImage, Area
from ihome.utils.logger import logger
from ihome.utils import statusCode

from ihome.utils.views import LoginRequiredJSONMixin


class DetailView(View):
    """房屋详情接口"""

    def get(self, request, house_id):

        user = request.user

        if not user.is_authenticated:
            user_id = -1
        else:
            user_id = user.id

        try:
            house = House.objects.get(pk=house_id)
        except Exception as e:
            logger.info('房屋数据查询错误：', e)
            return JsonResponse({
                'errno': statusCode.DBERR,
                'errmsg': "数据库查询错误"
            })

        def get_comment(order):
            """序列化评论信息"""
            return {
                'comment': order.comment,
                'ctime': order.update_time,
                'user_name': order.user.username
            }

        house_detail = {
            "acreage": house.acreage,
            "address": house.address,
            "beds": house.beds,
            "capacity": house.capacity,
            "comments": [get_comment(order) for order in house.order_set.all()],
            "deposit": house.deposit,
            "facilities": [fa_obj.id for fa_obj in house.facility.all()],
            "hid": house.id,
            "img_urls": [img_obj.url.url for img_obj in house.houseimage_set.all()],
            "max_days": house.max_days,
            "min_days": house.min_days,
            "price": house.price,
            "room_count": house.room_count,
            "title": house.title,
            "unit": house.unit,
            "user_avatar": house.user.avatar.url,
            "user_id": house.user.id,
            "user_name": house.user.username
        }

        return JsonResponse({
            'data': {
                'house': house_detail,
                'user_id': user_id,
            },
            'errno': statusCode.OK,
            'errmsg': "OK"
        })


class IndexHomeView(View):
    """首页房屋推荐"""

    def get(self, request):

        try:
            houses = House.objects.filter(is_active=True)
        except Exception as e:
            logger.info('房屋数据查询错误：', e)
            return JsonResponse({
                'errno': statusCode.DBERR,
                'errmsg': "数据库查询错误"
            })

        import random
        _list = random.sample(range(0, len(houses)), len(houses))

        house_list = [{
            'house_id': houses[i].id,
            'img_url': houses[i].index_image_url.url,
            'title': houses[i].title
        }for i in _list]

        return JsonResponse({
            'data': house_list,
            'errno': statusCode.OK,
            'errmsg': "OK"
        })


class HomeImgView(LoginRequiredJSONMixin, View):
    """房源图片上传接口"""

    def post(self, request, house_id):

        house_img = request.FILES.get('house_image', None)

        if house_img is None:
            return JsonResponse({'code': statusCode.NODATA, 'errmsg': 'NODATA'},
                                json_dumps_params={'ensure_ascii': False})

        try:
            house = House.objects.get(pk=house_id)

            try:
                house.index_image_url.url
            except Exception as e:
                house.index_image_url = house_img
                house.save()

            house_img = HouseImage.objects.create(
                house=house,
                url=house_img,
            )
        except Exception as e:
            return JsonResponse({'code': statusCode.DATAERR, 'errmsg': 'DATAERR'},
                                json_dumps_params={'ensure_ascii': False})

        return JsonResponse({
            'data': {
                'url': house_img.url.url
            },
            'errno': statusCode.OK,
            'errmsg': "图片上传成功"
        })


class AreaView(View):
    """城区列表接口"""

    def get(self, request):
        try:
            # 获取地区所有对象
            areas = Area.objects.all()
        except Exception as e:
            logger.info(e)
            return JsonResponse({'errno': statusCode.DBERR, 'errmsg': '没有地区信息'})

        area_list = []
        for area in areas:
            area_list.append({
                'aid': area.id,
                'aname': area.name
            })

        return JsonResponse({
            'errno': statusCode.OK,
            'errmsg': '获取成功',
            'data': area_list
        })


class AnnounceHouses(View):

    def get(self, request):
        """房屋搜索接口"""

        page = request.GET.get('p')
        aid = request.GET.get('aid')
        start_day = request.GET.get('sd')
        end_day = request.GET.get('ed')
        sort_key = request.GET.get('sk')

        my_order_by = '-create_time'
        if sort_key == 'booking':
            my_order_by = '-order_count'
        elif sort_key == 'price-inc':
            my_order_by = 'price'
        elif sort_key == 'price-des':
            my_order_by = '-price'

        if start_day:
            start_day = datetime.strptime(start_day, '%Y-%m-%d').date()
        if end_day:
            end_day = datetime.strptime(end_day, '%Y-%m-%d').date()

        valid_houses = []

        def get_vaild_houses(houses, start_day, end_day):
            for house in houses:
                try:
                    if all([start_day, end_day]):
                        orders = house.order_set.filter(Q(end_date__gt=start_day) | Q(begin_date__gt=end_day))
                    elif start_day:
                        orders = house.order_set.filter(end_date__gt=start_day)
                    elif end_day:
                        orders = house.order_set.filter(begin_date__gt=end_day)
                    else:
                        orders = False
                except Exception as e:
                    raise e

                if not orders:
                    valid_houses.append(house)

        # 选了地区
        if aid:
            try:
                houses = House.objects.filter(area_id=aid, is_active=True).order_by(my_order_by)
                get_vaild_houses(houses, start_day, end_day)
            except Exception as e:
                logger.info('数据查询错误：', e)
                return JsonResponse({'errno': statusCode.DBERR, 'errmsg': '数据查询错误'})

        # 没选地区
        else:
            try:
                houses = House.objects.filter(is_active=True).order_by(my_order_by)
                get_vaild_houses(houses, start_day, end_day)
            except Exception as e:
                logger.info('数据查询错误：', e)
                return JsonResponse({'errno': statusCode.DBERR, 'errmsg': '数据查询错误'})

        # 构建分页器参数-获取分页器对象
        paginator = Paginator(valid_houses, 5)
        try:
            # 找对象的方法获取所需的页数据
            page_housess = paginator.page(int(page))
        except Exception as e:
            return JsonResponse({'errno': statusCode.DBERR, 'errmsg': '数据查询错误'})


        house_list = []
        for house in page_housess:
            house_list.append({
                "address": house.address,
                "area_name": house.area.name,
                "ctime": house.create_time,
                "house_id": house.id,
                "img_url": house.index_image_url.url,
                "order_count": house.order_count,
                "price": house.price,
                "room_count": house.room_count,
                "title": house.title,
                "user_avatar": house.user.avatar.url
            })

        return JsonResponse({
            'data': {
                'houses': house_list,
                'total_page': paginator.num_pages,
            },
            'errno': statusCode.OK,
            'errmsg': '获取成功',
        })

    def post(self, request):
        """发布房源接口"""

        user = request.user

        if not user.is_authenticated:
            return JsonResponse({'errno': statusCode.SESSIONERR, 'errmsg': '未登录'})

        house_dict = json.loads(request.body.decode())
        title = house_dict.get('title')
        price = house_dict.get('price')
        area_id = house_dict.get('area_id', '1')
        address = house_dict.get('address')
        room_count = house_dict.get('room_count')
        acreage = house_dict.get('acreage')
        unit = house_dict.get('unit')
        capacity = house_dict.get('capacity')
        beds = house_dict.get('beds')
        deposit = house_dict.get('deposit')
        min_days = house_dict.get('min_days')
        max_days = house_dict.get('max_days')
        facility = house_dict.get('facility')

        if not all([title, price, area_id, address, room_count, acreage, unit, capacity, beds, deposit, min_days, max_days, facility]):
            return JsonResponse({'code': statusCode.PARAMERR, 'errmsg': '参数错误'})

        # 严谨
        if not (re.match('^(\d+)(\.\d+)?$', price) or re.match('^(\d+)(\.\d+)?$', deposit)):
            return JsonResponse({'code': statusCode.PARAMERR, 'errmsg': '参数错误'})

        price = '{0:.2f}'.format(float(price))
        deposit = '{0:.2f}'.format(float(deposit))

        try:
            house = House()
            house.area_id = area_id
            house.title = title
            house.price = int(float(price)*100)
            house.address = address
            house.room_count = room_count
            house.acreage = acreage
            house.unit = unit
            house.capacity = capacity
            house.beds = beds
            house.deposit = int(float(deposit)*100)
            house.min_days = min_days
            house.max_days = max_days
            house.user = user
            house.save()

            house.facility.add(*facility)
        except Exception as e:
            logger.info('数据查询错误：', e)
            return JsonResponse({'errno': statusCode.DBERR, 'errmsg': '数据查询错误'})

        return JsonResponse({'errno': statusCode.OK, 'errmsg': '发布成功',
                             'data': {
                                 'house_id': house.id,
                             }
                             })
